#region Copyright (c) 2003, newtelligence AG. All rights reserved.
/*
// Copyright (c) 2003, newtelligence AG. (http://www.newtelligence.com)
// All rights reserved.
//  
// Redistribution and use in source and binary forms, with or without modification, are permitted 
// provided that the following conditions are met: 
//  
// (1) Redistributions of source code must retain the above copyright notice, this list of 
// conditions and the following disclaimer. 
// (2) Redistributions in binary form must reproduce the above copyright notice, this list of 
// conditions and the following disclaimer in the documentation and/or other materials 
// provided with the distribution. 
// (3) Neither the name of the newtelligence AG nor the names of its contributors may be used 
// to endorse or promote products derived from this software without specific prior 
// written permission.
//      
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -------------------------------------------------------------------------
//
//
*/
#endregion

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Resources;
using System.Reflection;
using System.Collections;

namespace newtelligence.Web.UI.WebControls
{
    internal class ResourceStrings
    {
        static ResourceManager resmgr = new ResourceManager("newtelligence.Web.UI.WebControls.StringTables",typeof(ResourceStrings).Assembly);

        public static string Get(string index)
        {
            return resmgr.GetString(index);
        }

    }

	/// <summary>
	/// Summary description for DHTMLEditControl.
	/// </summary>
	[DefaultProperty("Text"),
	 ToolboxData("<{0}:DHTMLEditControl runat=server></{0}:DHTMLEditControl>")]
	public class DHTMLEditControl : System.Web.UI.WebControls.WebControl,
		                            IRenderControlImage 
	{
		private string text;
		private string name;
		private System.Web.UI.HtmlControls.HtmlSelect ddlFormat;
		private System.Web.UI.HtmlControls.HtmlSelect ddlFontFace;
		private System.Web.UI.HtmlControls.HtmlSelect ddlFontSize;
		private System.Web.UI.HtmlControls.HtmlSelect ddlFontColor;
        private System.Web.UI.HtmlControls.HtmlSelect ddlBackColor;
		private System.Web.UI.WebControls.Table tblEditor;
		private System.Web.UI.HtmlControls.HtmlGenericControl frmEditor;
		private System.Web.UI.WebControls.Panel topToolbarPanel;
		private System.Web.UI.WebControls.Panel bottomToolbarPanel;
		private System.Web.UI.WebControls.RadioButton wysiwygButton;
		private System.Web.UI.WebControls.RadioButton sourceButton;
					
		public DHTMLEditControl()
		{
			tblEditor = new System.Web.UI.WebControls.Table();
			frmEditor = new System.Web.UI.HtmlControls.HtmlGenericControl();
			ddlFormat = new System.Web.UI.HtmlControls.HtmlSelect();
			ddlFontFace = new System.Web.UI.HtmlControls.HtmlSelect();
			ddlFontSize = new System.Web.UI.HtmlControls.HtmlSelect();
			ddlFontColor = new System.Web.UI.HtmlControls.HtmlSelect();
            ddlBackColor = new System.Web.UI.HtmlControls.HtmlSelect();
			wysiwygButton = new System.Web.UI.WebControls.RadioButton();
			sourceButton = new System.Web.UI.WebControls.RadioButton();

			
			PopulateFormatList( );
			PopulateFontFaceList( );
			PopulateFontSizeList( );
			PopulateColorList( ResourceStrings.Get("text_color"), "forecolor", ddlFontColor );
            PopulateColorList( ResourceStrings.Get("text_backcolor"), "backcolor", ddlBackColor );
			
			this.BackColor = System.Drawing.Color.Gainsboro;
			this.BorderWidth=new Unit(1,UnitType.Pixel);
			this.Width = new Unit(300,UnitType.Pixel);
			this.Height = new Unit(200,UnitType.Pixel);
			this.Load += new EventHandler(this.OnLoad);
		}

		private void OnLoad( object sender, EventArgs e )
		{
			if ( this.Name == null || this.Name.Length == 0 )
			{
				this.Name = this.ID;
			}

			if ( Page.IsPostBack )
			{
				this.Text = Page.Request.Form[this.Name];
			}
            
		}

		private void InitializeEditor()
		{
			TableRow tr;
			TableCell td;
			
			tblEditor.ID="editorTable";
			tblEditor.CellPadding=2;
			tblEditor.CellSpacing=0;
			
			tblEditor.BorderWidth=this.BorderWidth;
			tblEditor.BorderStyle=this.BorderStyle;
			tblEditor.BorderColor=this.BorderColor;
			tblEditor.BackColor=this.BackColor;
			tblEditor.Width = this.Width;
			tblEditor.Height=this.Height;
			tblEditor.CssClass=this.CssClass;
            tblEditor.Style.Add("position","relative");
			

			tblEditor.Rows.Clear();
			tblEditor.Rows.Add(tr = new TableRow());
			tr.Cells.Add(td = new TableCell());
			
			td.Controls.Add(topToolbarPanel = new Panel());
			BuildToolbar( topToolbarPanel );
			
			td.Controls.Add(bottomToolbarPanel = new Panel());
			BuildFormattingBar(bottomToolbarPanel);

            tblEditor.Rows.Add(tr = new TableRow());
            tr.Cells.Add(td = new TableCell());
            td.Height=Unit.Percentage(98);
			td.Controls.Add(frmEditor);

            tblEditor.Rows.Add(tr = new TableRow());
            tr.Cells.Add(td = new TableCell());
			td.Controls.Add(wysiwygButton);

			wysiwygButton.Attributes.Add("onclick","DHTMLEditSetMode(true)");
			wysiwygButton.Checked=true;
			wysiwygButton.Text = ResourceStrings.Get("text_edit");
			wysiwygButton.GroupName = "SwitchModes";
			wysiwygButton.Font.Size = FontUnit.Point(8);
			td.Controls.Add(sourceButton);
			sourceButton.Attributes.Add("onclick","DHTMLEditSetMode(false)");
			sourceButton.Checked=false;
			sourceButton.Text = ResourceStrings.Get("text_html");
			sourceButton.GroupName = "SwitchModes";
			sourceButton.Font.Size = FontUnit.Point(8);
		}

		

		private string BuildEditorScriptBlock()
		{
			string editorID = frmEditor.ClientID;
			string editorTableID = tblEditor.ClientID;
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			
			sb.Append("<script language=JavaScript>\n");
			sb.Append("var rightCaret = String.fromCharCode(62);\n");
			sb.Append("var bLoad = false;\n");
			sb.Append("	var sHeader = \"<body style=\\\"margin-top: 3px; margin-bottom: 3px; margin-left: 3px; margin-right: 3px;\\\"\" + rightCaret;\n");
			sb.Append("	var wysiwygMode = true;\n");
			sb.Append("	var sel = null;\n");
			sb.Append("	var strErr = \"Formatting is only allowed in HTML Mode\";\n");
			sb.Append("	function DHTMLEditFormat (action,option) \n");
			sb.Append("{\n");
			sb.Append("			if (!wysiwygMode) \n");
			sb.Append("			{\n");
			sb.Append("				alert (strErr); "+editorID+".focus ();\n");
			sb.Append("				return;\n");
			sb.Append("			}\n");
			sb.Append("			if (option == \"removeFormat\") \n");
			sb.Append("			{\n");
			sb.Append("				action = option;\n");
			sb.Append("				option = null;\n");
			sb.Append("			}\n");
			sb.Append("			if (wysiwygMode) \n");
			sb.Append("			{\n");
			sb.Append("				if (option == null)\n");
			sb.Append("					"+editorID+".document.execCommand (action);\n");
			sb.Append("				else\n");
			sb.Append("					"+editorID+".document.execCommand (action, \"\", option);\n");
			sb.Append("				var s = "+editorID+".document.selection.createRange (), p = s.parentElement ()\n");
			sb.Append("					if ((p.tagName == \"FONT\") && (p.style.backgroundColor != \"\"))\n");
			sb.Append("						p.outerHTML = p.innerHTML;\n");
			sb.Append("				"+editorID+".focus ();\n");
			sb.Append("			} \n");
			sb.Append("			sel = null\n");
			sb.Append("			}\n");
			sb.Append("	function getEl (sTag, start) \n");
			sb.Append("{\n");
			sb.Append("					while ((start != null) && (start.tagName != sTag))\n");
			sb.Append("						start = start.parentElement;\n");
			sb.Append("					return start;\n");
			sb.Append("				}\n");
			sb.Append("	function DHTMLEditCreateLink () \n");
			sb.Append("	{\n");
			sb.Append("		if (!wysiwygMode) \n");
			sb.Append("		{\n");
			sb.Append("			alert (strErr);\n");
			sb.Append("			"+editorID+".focus ();\n");
			sb.Append("			return;\n");
			sb.Append("		}\n");
			sb.Append("		var isA = getEl ( \"A\", "+editorID+".document.selection.createRange().parentElement());\n");
			sb.Append("		var str = prompt (\"Enter a URL to link to:\", isA ? isA.href : \"http:\\/\\/\");\n");
			sb.Append("		if ((str!=null) && (str!=(\"http:\" + \"//\"))) \n");
			sb.Append("		{\n");
			sb.Append("			if ("+editorID+".document.selection.type == \"None\") \n");
			sb.Append("			{\n");
			sb.Append("				var sel = "+editorID+".document.selection.createRange ();\n");
			sb.Append("				sel.pasteHTML (\"<A HREF=\\\"\" + str + \"\\\"\" + rightCaret + str + \"</A\" + rightCaret + \" \");\n");
			sb.Append("				sel.select ();\n");
			sb.Append("			}\n");
			sb.Append("			else\n");
			sb.Append("				DHTMLEditFormat (\"CreateLink\", str);\n");
			sb.Append("		}\n");
			sb.Append("		else\n");
			sb.Append("			"+editorID+".focus ();\n");
			sb.Append("	}\n");
			sb.Append("function DHTMLEditSetMode (bNewMode) \n");
			sb.Append("{\n");
			sb.Append("	if (bNewMode != wysiwygMode) \n");
			sb.Append("	{\n");
			sb.Append("		if (bNewMode) \n");
			sb.Append("		{\n");
			sb.Append("			var sContents = "+editorID+".document.body.innerText;\n");
			sb.Append("			"+editorID+".document.open ();\n");
			sb.Append("			"+editorID+".document.write (sHeader);\n");
			sb.Append("			"+editorID+".document.close ();\n");
			sb.Append("			"+editorID+".document.body.innerHTML = sContents;\n");
			sb.Append("		}\n");
			sb.Append("		else \n");
			sb.Append("		{\n");
			sb.Append("			var fonts="+editorID+".document.body.all.tags (\"FONT\");\n");
			sb.Append("		\n");
			sb.Append("			for (var i=0; i < fonts.length; i++)\n");
			sb.Append("				if (fonts[i].style.backgroundColor != \"\")\n");
			sb.Append("					fonts[i].outerHTML = fonts[i].innerHTML;\n");
			sb.Append("			var sContents = "+editorID+".document.body.innerHTML;\n");
			sb.Append("			"+editorID+".document.open ();\n");
			sb.Append("			"+editorID+".document.write (\"<BODY style=\\\"font:10pt courier, monospace\\\"\" + rightCaret);\n");
			sb.Append("			"+editorID+".document.close ();\n");
			sb.Append("			"+editorID+".document.body.innerText = sContents;\n");
			sb.Append("		}\n");
			sb.Append("		wysiwygMode = bNewMode;\n");
			sb.Append("	}\n");
			sb.Append("	"+editorID+".focus ();\n");
			sb.Append("}\n");
			sb.Append("function getEditorContents () \n");
			sb.Append("{\n");
            sb.Append("	window.focus ();\n");
			sb.Append("	if (wysiwygMode) \n");
			sb.Append("	{\n");
			sb.Append("		return ("+editorID+".document.body.innerHTML);\n");
			sb.Append("	}\n");
			sb.Append("	else \n");
			sb.Append("	{\n");
			sb.Append("		return ("+editorID+".document.body.innerText);\n");
			sb.Append("	}\n");
			sb.Append("}\n");
			sb.Append("</script>");
			sb.Append("	<script event=\"onload\" for=\"window\">\n");
			sb.Append("	"+editorID+".document.designMode = 'On';\n");
			sb.Append("	bLoad = true;\n");
			sb.Append("	"+topToolbarPanel.ClientID+".style.visibility = '';\n");
			sb.Append("	if (document.all['"+this.Name+"'].value != '') {\n");
			sb.Append("		try {\n");
			sb.Append("			document.frames('"+editorID+"').document.write (sHeader);\n");
			sb.Append("			document.frames('"+editorID+"').document.write (document.all['"+this.Name+"'].value);\n");
			sb.Append("			} catch (e) {}\n");
			sb.Append("		}\n");
			sb.Append("			</script>\n");
	
			return sb.ToString();
		}

		private void BuildFormattingBar( Panel panel )
		{
			TableRow tr;
			TableCell td;
			Table topToolbarTable;

			panel.ID = "tb2";
			panel.BackColor=this.BackColor;
			panel.Style.Add("OVERFLOW","hidden");
			panel.Width = new Unit(100,UnitType.Percentage);
			panel.Height = new Unit(25,UnitType.Pixel);
			panel.Attributes.Add("onselectstart","return false");
			panel.Attributes.Add("ondragstart","return false");
        
			panel.Controls.Add(topToolbarTable = new Table());
			topToolbarTable.CellSpacing=2;
			topToolbarTable.CellPadding=0;
			topToolbarTable.Style.Add("MARGIN-BOTTOM","2pt");
			topToolbarTable.Style.Add("PADDING-TOP","1pt");
			topToolbarTable.Rows.Add(tr = new TableRow());
			tr.Cells.Add( td = new TableCell() );
			td.HorizontalAlign = HorizontalAlign.Center;
			td.Wrap = false;
			
			td.Controls.Add(ddlFormat);
			td.Controls.Add(ddlFontFace);
			td.Controls.Add(ddlFontSize);
			td.Controls.Add(ddlFontColor);
            td.Controls.Add(ddlBackColor);
		}

		void IRenderControlImage.Render( HttpContext Context, string[] Args )
		{
			
			System.IO.Stream stm = GetType().Assembly.GetManifestResourceStream("newtelligence.Web.UI.WebControls.DHTMLEditControl.gif");
			byte[] buf = new byte[stm.Length];
			stm.Read(buf,0,(int)stm.Length);
			Context.Response.OutputStream.Write(buf,0,buf.Length);
			Context.Response.ContentType="image/gif";
		}

		private void BuildToolbar( Panel panel )
		{
            int offset = 0;
			panel.ID = "tb3";
			panel.BackColor=this.BackColor;
			panel.Style.Add("overflow","hidden");
            panel.Style.Add("position","relative");
			panel.Width = new Unit(100,UnitType.Percentage);
			panel.Height = new Unit(25,UnitType.Pixel);
            			
			int[] buttons=new int[]{24,23,23,4,23,23,23,4,23,23,23,23,4,23,23,4,23};
			string[] action=new string[]{"bold","italic","underline","","justifyleft","justifycenter","justifyright","","insertorderedlist","insertunorderedlist","outdent","indent","","BlockDirLTR","BlockDirRTL","","createLink"};
			string[] tooltip=new string[]{ResourceStrings.Get("tooltip_bold"),ResourceStrings.Get("tooltip_italic"),ResourceStrings.Get("tooltip_underline"),"",ResourceStrings.Get("tooltip_left"),ResourceStrings.Get("tooltip_center"),ResourceStrings.Get("tooltip_right"),"",ResourceStrings.Get("tooltip_numbers"),ResourceStrings.Get("tooltip_bullets"),ResourceStrings.Get("tooltip_indent_out"),ResourceStrings.Get("tooltip_indent_in"),"",ResourceStrings.Get("tooltip_ltr"),ResourceStrings.Get("tooltip_rtl"),"",ResourceStrings.Get("tooltip_hyperlink")};
			int left=0;  // startoffset
			for (int i=0;i<buttons.Length;i++) 
			{
				System.Web.UI.HtmlControls.HtmlGenericControl span;
				System.Web.UI.HtmlControls.HtmlImage img;

				panel.Controls.Add(
					span = new System.Web.UI.HtmlControls.HtmlGenericControl("div"));
				span.Style.Add("display","inline-block");
				span.Style.Add("position","absolute");
                span.Style.Add("margin","0px");
				span.Style.Add("padding","0px");
				span.Style.Add("height","26px");
				span.Style.Add("left",(left+offset).ToString()+"px");
                span.Style.Add("width",buttons[i].ToString()+"px");
				span.Style.Add("clip","rect(0px "+buttons[i].ToString()+"px 25px 0px)");
				span.Style.Add("overflow","hidden");
				span.Controls.Add(img = new System.Web.UI.HtmlControls.HtmlImage() );
				img.Border=0;
				img.Src=ControlImageModule.GetImageHRef(Context,GetType(),null);
				img.Style.Add("position","absolute");
				img.Style.Add("top","0px");
				img.Style.Add("left",(left*-1).ToString()+"px");
				img.Width=340;
				img.Height=50;

				if (buttons[i]!=4) 
				{
					img.Attributes.Add("onmouseover","this.style.top=-25");
					img.Attributes.Add("onmouseout","this.style.top=0");
					if (action[i]!="createLink") 
					{
						img.Attributes.Add("onclick","DHTMLEditFormat('" + action[i] + "');this.style.top=0");
					}
					else
					{
						img.Attributes.Add("onclick","DHTMLEditCreateLink();this.style.top=0");
					}
					img.Alt=tooltip[i];
				}
				left+=buttons[i] ;
			}
		}

		private void InitializeEditorFrame()
		{
			if ( this.Site != null && this.Site.DesignMode == true )
			{
				frmEditor.TagName="div";
				frmEditor.Style.Add("border-width","1px");
				frmEditor.Style.Add("position","relative");
				frmEditor.Style.Add("width","100%");
				frmEditor.Style.Add("height","100%"); //??
				frmEditor.Attributes.Add("name","idEdit");
				frmEditor.Style.Add("background-color","white");
				frmEditor.Style.Add("border-style","inset");
				frmEditor.InnerHtml=this.Text;
			}
			else
			{
				frmEditor.TagName="iframe";
				frmEditor.Attributes.Add("ID",frmEditor.ClientID);
				frmEditor.Attributes.Add("frameborder","1");
				frmEditor.Attributes.Add("width","100%");
				frmEditor.Attributes.Add("height","100%"); //??
                
				if ( Page != null && 
					!Page.IsStartupScriptRegistered(frmEditor.ClientID) )
				{
					Page.RegisterStartupScript(frmEditor.ClientID,BuildEditorScriptBlock());
					
				}
			}
		}

		private void PopulateFormatList( )
		{
			ListItem[] items = new ListItem[] 
			{
				new ListItem(ResourceStrings.Get("text_style"),"<P>"),
				new ListItem(ResourceStrings.Get("text_style_normal"),"<P>"),
				new ListItem(ResourceStrings.Get("text_style_head1"),"<H1>"),
				new ListItem(ResourceStrings.Get("text_style_head2"),"<H2>"),
				new ListItem(ResourceStrings.Get("text_style_head3"),"<H3>"),
				new ListItem(ResourceStrings.Get("text_style_head4"),"<H4>"),
				new ListItem(ResourceStrings.Get("text_style_head5"),"<H5>"),
				new ListItem(ResourceStrings.Get("text_style_head6"),"<H6>"),
				new ListItem(ResourceStrings.Get("text_style_pre"),"<PRE>")
			};

			ddlFormat.Attributes.Add("onchange","DHTMLEditFormat('formatBlock',this[this.selectedIndex].value);this.selectedIndex=0");
			ddlFormat.Items.Clear();
			ddlFormat.Items.AddRange( items );
		}

		private void PopulateFontFaceList( )
		{
			ListItem[] items = new ListItem[] 
			{
				new ListItem(ResourceStrings.Get("text_font"),"Geneva,Arial,Sans-Serif"),
				new ListItem("Helvetica","Geneva,Arial,Sans-Serif"),
				new ListItem("Verdana","Verdana,Geneva,Arial,Helvetica,Sans-Serif"),
				new ListItem("Times","Times New Roman,Times,Serif"),
				new ListItem("Courier","Courier New,Courier, Monospace"),
				new ListItem("Arabic Transparent","Arabic Transparent")
			};
			ddlFontFace.Attributes.Add("onchange","DHTMLEditFormat('fontname',this[this.selectedIndex].value);this.selectedIndex=0");
			ddlFontFace.Items.Clear();
			ddlFontFace.Items.AddRange( items );
            
		}

		private void PopulateFontSizeList( )
		{
			ListItem[] items = new ListItem[] 
			{
				new ListItem(ResourceStrings.Get("text_size"),"1"),
				new ListItem("1","1"),
				new ListItem("2","2"),
				new ListItem("3","3"),
				new ListItem("4","4"),
				new ListItem("5","5"),
				new ListItem("6","6"),
				new ListItem("7","7")
			};

			ddlFontSize.Attributes.Add("onchange","DHTMLEditFormat('fontSize',this[this.selectedIndex].value);this.selectedIndex=0");
			ddlFontSize.Items.Clear();
			ddlFontSize.Items.AddRange( items );
            
		}

		private void PopulateColorList(string headText, string cmd, System.Web.UI.HtmlControls.HtmlSelect ddl)
		{

			ArrayList items = new ArrayList();
 
            items.Add( new ListItem(headText,"#000000") );
            foreach( PropertyInfo prop in typeof(System.Drawing.Color).GetProperties(BindingFlags.Static|BindingFlags.Public) )
            {
                System.Drawing.Color color = (System.Drawing.Color)prop.GetValue(null,null);
                items.Add( new ListItem(color.Name,String.Format("#{0:x}{1:x}{2:x}{3:x}{4:x}{5:x}",color.R/16,color.R%16,color.G/16,color.G%16,color.B/16,color.B%16)) );
            }
			
			ddl.Attributes.Add("onchange","DHTMLEditFormat('"+cmd+"',this[this.selectedIndex].value);this.selectedIndex=0");
			ddl.Items.Clear();
			ddl.Items.AddRange( items.ToArray(typeof(ListItem)) as ListItem[] );
            foreach( ListItem li in ddl.Items )
            {
                li.Attributes.Add("style","background-color:"+li.Value+";color:#ffffff");
            }
		}
		
		[Bindable(true), 
			Category("Appearance"), 
			DefaultValue("")] 
		public string Text 
		{
			get
			{
				return text;
			}

			set
			{
				text = value;
			}
		}

		[Bindable(true), 
		Category("Appearance"), 
		DefaultValue("")] 
		public string Name 
		{
			get
			{
				return name;
			}

			set
			{
				name = value;
			}
		}

		
        protected override void OnPreRender(EventArgs e)
        {
            Page.RegisterOnSubmitStatement(this.Name+"Submit", this.Name+".value=getEditorContents();");
            base.OnPreRender (e);
        }

		/// <summary> 
		/// Render this control to the output parameter specified.
		/// </summary>
		/// <param name="output"> The HTML writer to write out to </param>
		protected override void Render(HtmlTextWriter output)
		{
			Controls.Clear();
			Controls.Add(tblEditor);
			InitializeEditor();
			InitializeEditorFrame();
            Page.RegisterHiddenField(this.Name, this.Text); 
           
			RenderChildren(output);
			
		}
	}
}
